<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');


class MY_Template
{
	var $index =0;
	var $block_search  = array();
	var $block_replace = array();
	var $sub_tpls = array();
	var $template_root ='resource';
	var $template_dir = 'default' ;


	public function __construct()
	{
		$this->config =& load_class('Config', 'core');
		$template_dir = $this->config->item('template_dir');
		$template_root = $this->config->item('template_root');
		if(empty($template_dir))
		{
			$template_dir='default';
		}
		if(empty($template_root))
		{
			$template_root='resource';
		}
		$this->template_dir =$template_dir;
		$this->template_root =$template_root;
	}

	public function parse_template($tpl) {
		
		//包含模板
		$this->sub_tpls = array($tpl);

		$tplfile = FCPATH.'./'.$this->template_root.'/'.$tpl.'.htm';

		$objfile = APPPATH.'./views/tpl_cache/'.str_replace('/','_',$tpl).'.php';
		
		//read
		if(!file_exists($tplfile)) {
			$tplfile = str_replace('/'.$this->template_dir.'/', '/default/', $tplfile);
		}
		$template = $this->sreadfile($tplfile);
		if(empty($template)) {
			exit("Template file : $tplfile Not found or have no access!");
		}

		//模板
		$template = preg_replace("/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie", "\$this->readtemplate('\\1')", $template);
		//处理子页面中的代码
		$template = preg_replace("/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie", "\$this->readtemplate('\\1')", $template);

		//时间处理
		$template = preg_replace("/\<\!\-\-\{date\((.+?)\)\}\-\-\>/ie", "\$this->datetags('\\1')", $template);
	 
		//PHP代码
		$template = preg_replace("/\<\!\-\-\{eval\s+(.+?)\s*\}\-\-\>/ies", "\$this->evaltags('\\1')", $template);

		//PHP代码
		$template = preg_replace("/\<\!\-\-\{function\s+(.+?)\s*\}\-\-\>/ies", "\$this->functiontags('\\1')", $template);

		//开始处理
		//变量
		$var_regexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";
		$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
		$template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);
		$template = preg_replace("/(\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\.([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/s", "\\1['\\2']", $template);
		$template = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=\\1?>", $template);
		$template = preg_replace("/$var_regexp/es", "\$this->addquote('<?=\\1?>')", $template);
		$template = preg_replace("/\<\?\=\<\?\=$var_regexp\?\>\?\>/es", "\$this->addquote('<?=\\1?>')", $template);
		//逻辑
		$template = preg_replace("/\{elseif\s+(.+?)\}/ies", "\$this->stripvtags('<?php } elseif(\\1) { ?>','')", $template);
		$template = preg_replace("/\{else\}/is", "<?php } else { ?>", $template);
		//循环
		for($i = 0; $i < 6; $i++) {
			$template = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies", "\$this->stripvtags('<?php if(is_array(\\1)) { foreach(\\1 as \\2) { ?>','\\3<?php } } ?>')", $template);
			$template = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies", "\$this->stripvtags('<?php if(is_array(\\1)) { foreach(\\1 as \\2 => \\3) { ?>','\\4<?php } } ?>')", $template);
			$template = preg_replace("/\{if\s+(.+?)\}(.+?)\{\/if\}/ies", "\$this->stripvtags('<?php if(\\1) { ?>','\\2<?php } ?>')", $template);
		}
		//常量
		$template = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s", "<?=\\1?>", $template);
		
		//替换
		if(!empty($this->block_search)) {
			$template = str_replace($this->block_search, $this->block_replace, $template);
		}
		
		//换行
		$template = preg_replace("/ \?\>[\n\r]*\<\? /s", " ", $template);
		
		//附加处理

		$template = "<?php if (!defined('BASEPATH')) exit('No direct script access allowed');?>$template";
		//write
		if(!$this->swritefile($objfile, $template)) {
			exit("File: $objfile can not be write!");
		}
	}

	function addquote($var) {
		return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
	}

	function striptagquotes($expr) {
		$expr = preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr);
		$expr = str_replace("\\\"", "\"", preg_replace("/\[\'([a-zA-Z0-9_\-\.\x7f-\xff]+)\'\]/s", "[\\1]", $expr));
		return $expr;
	}

	function evaltags($php) {

		$this->index ++;
		$search = "<!--EVAL_TAG_{$this->index}-->";
		$this->block_search[$this->index] = $search;
		$this->block_replace[$this->index] = "<?php ".stripvtags($php)." ?>";
		
		return $search;
	}

	function datetags($parameter) {

		$this->index++;
		$search = "<!--DATE_TAG_{$this->index}-->";
		$this->block_search[$this->index] = $search;
		$this->block_replace[$this->index] = "<?php echo unix_to_human($parameter); ?>";
		return $search;
	}

	function functiontags($parameter) {

		$this->index++;
		$search = "<!--FUNCTION_TAG_{$this->index}-->";
		$this->block_search[$this->index] = $search;
		$this->block_replace[$this->index] = "<?php echo $parameter; ?>";
		return $search;
	}

	 
	function stripvtags($expr, $statement='') {
		$expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr));
		$statement = str_replace("\\\"", "\"", $statement);
		return $expr.$statement;
	}

	function readtemplate($name) {
		
		$tpl = strexists($name,'/')?$name:"template/".$this->template_dir."/$name";
		$tplfile = BASEPATH.'./'.$template_root.'/'.$tpl.'.htm';
		
		$this->sub_tpls[] = $tpl;
		
		if(!file_exists($tplfile)) {
			$tplfile = str_replace('/'.$this->template_dir.'/', '/default/', $tplfile);
		}
		$content = sreadfile($tplfile);
		return $content;
	}

	//获取文件内容
	function sreadfile($filename) {
		$content = '';
		if(function_exists('file_get_contents')) {
			@$content = file_get_contents($filename);
		} else {
			if(@$fp = fopen($filename, 'r')) {
				@$content = fread($fp, filesize($filename));
				@fclose($fp);
			}
		}
		return $content;
	}

	//写入文件
	function swritefile($filename, $writetext, $openmod='w') {
		if(@$fp = fopen($filename, $openmod)) {
			flock($fp, 2);
			fwrite($fp, $writetext);
			fclose($fp);
			return true;
		} else {
			return false;
		}
	}
}
?>